package com.hjy.test;

import io.netty.bootstrap.ServerBootstrap;
import io.netty.channel.*;
import io.netty.channel.nio.NioEventLoopGroup;
import io.netty.channel.socket.SocketChannel;
import io.netty.channel.socket.nio.NioServerSocketChannel;

import java.nio.charset.StandardCharsets;

public class PipeLineServer {
    public static void main(String[] args) {
        new ServerBootstrap()
                .group(new NioEventLoopGroup())
                .channel(NioServerSocketChannel.class)
                .childHandler(new ChannelInitializer<SocketChannel>() {
                    @Override
                    protected void initChannel(SocketChannel channel) throws Exception {
                        //再 SocketChannel 中 pipeline 中添加 hander
                        //pipeline 中handler 是带 head 和 tail 节点的双向链表 实际结构为
                        //head<-> handler1<-> ..... handler4<->tail
                        //Inbound 主要处理入站操作,一般都是读，发生入站操作时会触发Inbound 方法
                        //入站是 handler 是从 handler 向后调用的
                        channel.pipeline().addLast("handler1", new ChannelInboundHandlerAdapter(){
                            @Override
                            public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception {
                                System.out.println(Thread.currentThread().getName() +" Inbound handler1");
                                //父类方法中会调用 fireChannelRead
                                //将数据传递给下一个Handler
                                super.channelRead(ctx, msg);
                            }
                        });
                        channel.pipeline().addLast("handler2", new ChannelInboundHandlerAdapter(){
                            @Override
                            public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception {
                                System.out.println(Thread.currentThread().getName() +" Inbound handler2");
                                channel.writeAndFlush(ctx.alloc().buffer().writeBytes("Server ...".getBytes(StandardCharsets.UTF_8)));
                                super.channelRead(ctx, msg);
                            }
                        });

                        channel.pipeline().addLast("handler3", new ChannelOutboundHandlerAdapter(){
                            @Override
                            public void write(ChannelHandlerContext ctx, Object msg, ChannelPromise promise) throws Exception {
                                System.out.println(Thread.currentThread().getName() +" Outbound handler1");
                                super.write(ctx, msg, promise);
                            }
                        });
                        channel.pipeline().addLast("handler4", new ChannelOutboundHandlerAdapter(){
                            @Override
                            public void write(ChannelHandlerContext ctx, Object msg, ChannelPromise promise) throws Exception {
                                System.out.println(Thread.currentThread().getName() +" Outbound handler2");
                                super.write(ctx, msg, promise);
                            }
                        });
                    }
                }).bind(8080);

    }
}
